package org.axed.user.client.jsni;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Grid;
import org.axed.user.client.AxedArea;
import org.axed.user.client.axessory.HPositionBar;
import org.axed.user.client.axessory.InfoBar;
import org.axed.user.client.axessory.VPositionBar;
import org.axed.user.client.axessory.VimBar;
import org.axed.user.client.axessory.VimInput;
import org.timepedia.exporter.client.Exportable;


/**
 * An implementation to allow native JS to simply create a more complicated
 * axessoried axedarea withing one line.
 * @gwt.exportPackage axed
 * @gwt.export
 */
public class AxedBox implements Exportable {
	public static final int HPOSBAR  = 0x01;
	public static final int VPOSBAR  = 0x02;
	public static final int VIMISH   = 0x04;
	public static final int GETFOCUS = 0x08;
	
	AxedArea axedArea;
	HPositionBar hPosBar;
	VPositionBar vPosBar;
	//InfoBar infoBar;
	VimInput vimInput;
	VimBar vimBar;
	boolean showHPosBar;
	boolean showVPosBar;
	boolean haveVimInput;
	Grid grid;

	private final int PRI_HPOSBAR   =  axedArea.LISTENER_PRIORITY_EXTEND + 1;
	private final int PRI_VPOSBAR   =  axedArea.LISTENER_PRIORITY_EXTEND + 2;
	private final int PRI_INFOBAR   =  axedArea.LISTENER_PRIORITY_EXTEND + 3;
	private final int PRI_UNDOVIEW  =  axedArea.LISTENER_PRIORITY_EXTEND + 4;
	private final int PRI_VIMBAR    =  axedArea.LISTENER_PRIORITY_EXTEND - 1;
	private int flags;

	public AxedBox(Element div, int flags) {
		this.flags = flags;
		axedArea = new AxedArea(null, 800, null);
		hPosBar = new HPositionBar(axedArea, null);
		vPosBar = new VPositionBar(axedArea, null, 3);
		//infoBar = new InfoBar(axedArea, label);
		vimBar = new VimBar(axedArea, null);
		vimInput = new VimInput(axedArea, vimBar);
		//axedArea.addListener(infoBar, PRI_INFOBAR);

		grid = new Grid(3, 2);
		grid.setCellSpacing(0);
		grid.setCellPadding(0);
		grid.setBorderWidth(0);
		grid.setWidget(0, 1, hPosBar);

		if ((flags & VPOSBAR) != 0) {
			grid.setWidget(1, 0, vPosBar);
			DOM.setStyleAttribute(axedArea.getElement(), "borderLeft", "none");
		} else {
			grid.setText(1, 0, "");
			DOM.setStyleAttribute(axedArea.getElement(), "borderLeft", "1px solid");
		}

		grid.setWidget(1, 1, axedArea);
		grid.getRowFormatter().setVisible(2, false);
		DOM.appendChild(div, grid.getElement());
		
		if ((flags & HPOSBAR) != 0) {
			DOM.setStyleAttribute(axedArea.getElement(), "borderTop", "none");
		} else {
			grid.getRowFormatter().setVisible(0, false);
			DOM.setStyleAttribute(axedArea.getElement(), "borderTop", "1px solid");
		}

		showHPosBar = false;
		showVPosBar = false;
		haveVimInput = false;
		showHidePositionBars((flags & HPOSBAR) != 0, (flags & VPOSBAR) != 0); 
		setVimInput((flags & VIMISH) != 0);
	
		DeferredCommand.add(new Command() {
		 	public void execute() {
				hPosBar.resized();
				if ((AxedBox.this.flags & GETFOCUS) != 0) {
					axedArea.setFocus(true);
				}
			}
		});
	}
	
	/**
	 * Shows or hides the positon bars.
	 *
	 * @return true if the position of the widget has been changed.
	 */
	private boolean showHidePositionBars(boolean showHPosBar, boolean showVPosBar) {
		boolean redraw = false;
		if (this.showHPosBar && !showHPosBar) {
			// turns hposbar off.
			grid.setText(0, 1, "");
			grid.getRowFormatter().setVisible(0, false);
			this.showHPosBar = false;
			redraw = true;
			axedArea.removeListener(hPosBar);
			DOM.setStyleAttribute(axedArea.getElement(), "borderTop", "1px solid");
		}
		if (this.showVPosBar && !showVPosBar) {
			// turns vposbar off.
			grid.setText(1, 0, "");
			this.showVPosBar = false;
			redraw = true;
			axedArea.removeListener(vPosBar);
			DOM.setStyleAttribute(axedArea.getElement(), "borderLeft", "1px solid");
		}

		if (!this.showHPosBar && showHPosBar) {
			// turns hposbar on.
			grid.setWidget(0, 1, hPosBar);
			grid.getRowFormatter().setVisible(0, true);
			this.showHPosBar = true;
			redraw = true;
			axedArea.addListener(hPosBar, PRI_HPOSBAR);
			DOM.setStyleAttribute(axedArea.getElement(), "borderTop", "none");
		}
		if (!this.showVPosBar && showVPosBar) {
			// turns vposbar on.
			grid.setWidget(1, 0, vPosBar);
			this.showVPosBar = true;
			redraw = true;
			axedArea.addListener(vPosBar, PRI_VPOSBAR);
			DOM.setStyleAttribute(axedArea.getElement(), "borderLeft", "none");
		}
		
		return redraw;
	}
	
	public void setVimInput(boolean haveVimInput) {
		if (haveVimInput && !this.haveVimInput) {
			// sets to vim input
			this.haveVimInput = true;
			axedArea.replaceInputHandler(vimInput);
			axedArea.addListener(vimBar, PRI_VIMBAR);
			//axedArea.removeListener(infoBar);
			//label.setText("");
			grid.setWidget(2, 1, vimBar);
			grid.getRowFormatter().setVisible(2, true);
			axedArea.refresh();
		}

		if (!haveVimInput && this.haveVimInput) {
			// sets to normal input
			this.haveVimInput = false;
			axedArea.restoreInputHandler();
			axedArea.removeListener(vimBar);
			//axedArea.addListener(infoBar, PRI_INFOBAR);
			grid.setText(2, 1, "");
			grid.getRowFormatter().setVisible(2, false);
			axedArea.refresh();
		}
	}
}
